<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        height: 500px;
      }
    </style>
  </head>
  <body>
    <script>
      // 定义滚动事件监听
      // 节流：我们这里的节流指的就是在自定义的一段时间内让时间进行触发
      function myThrottle(handle, wait) {
        if (typeof handle !== "function")
          throw new Error("handle must be a function");

        if (typeof wait === "undefined") wait = 400;

        let timer = null;
        let previous = 0; // 定义变量记录当前次执行的时刻时间点
        return function (...args) {
          const now = new Date();
          const self = this;
          let interval = wait - (now - previous);

          if (interval <= 0) {
            // 此时就说明非高频次操作，可以执行 handle
            // 浏览器执行频率和设置定时器频率一直，需要手动置空定时器
            clearTimeout(timer);
            timer = null;
            handle.call(self, ...args);
            previous = new Date();
          } else if (!timer) {
            // 当我们发现当前系统中有一个定时器了，就意味着我们不需要在开启定时器
            // 此时就说明这次的操作发生了我们定义的频次的频次时间范围内，那就不应该执行 handle
            // 只要有一个定时器执行一次就够了
            timer = setTimeout(() => {
              clearTimeout(timer);
              timer = null;
              handle.call(self, ...args);
              previous = new Date();
            }, interval);
          }
        };
      }

      function scrollFn() {
        console.log("滚动了");
      }

      window.onscroll = myThrottle(scrollFn);
      // window.onscroll = scrollFn;
    </script>
  </body>
</html>
